package bean.managed;

import entity.MasterProductionScheduleMonthlyEntity;
import bean.managed.util.JsfUtil;
import bean.session.MasterProductionScheduleMonthlyEntityFacade;

import entity.CalendarEntity;
import entity.CompletedGoodsEntity;
import entity.ExpectedYearOnYearGrowthEntity;
import entity.PlannedReserveEntity;
import entity.MasterProductionScheduleDailyEntity;
import entity.ProductPercentageQuantityEntity;
import entity.SalesForecastEntity;
import entity.SalesOrderEntity;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import managedbean.AbstractBacking;
import org.primefaces.component.datatable.DataTable;
import type.DayOfWeek;
import type.Month;
import type.ProductionType;

@ManagedBean(name = "masterProductionScheduleMonthlyEntityController")
@SessionScoped
public class MasterProductionScheduleMonthlyEntityController extends AbstractBacking implements Serializable {

    private MasterProductionScheduleMonthlyEntity current;
    private MasterProductionScheduleMonthlyEntity productionLine2;
    private DataModel items = null;
    private DataModel createItems = null;
    private DataModel createItems2 = null;
    @EJB
    private bean.session.MasterProductionScheduleMonthlyEntityFacade ejbFacade;
    @EJB
    private bean.session.MasterProductionScheduleDailyEntityFacade dailyEjbFacade;
    @EJB
    private bean.session.ExpectedYearOnYearGrowthEntityFacade yoyEjbFacade;
    private ExpectedYearOnYearGrowthEntity yoy;
    private long productionLine1PlannedQuantity = 0;
    private long productionLine2PlannedQuantity = 0;
    private DataTable dataTable;
    private DataTable dataTable2;
    private int plannedReserveClassicNuts;
    private int plannedReserveClassicFruits;
    private int plannedReservePremiumNuts;
    private int plannedReservePremiumFruits;
    private int plannedReserveClassicNuts2;
    private int plannedReserveClassicFruits2;
    private int plannedReservePremiumNuts2;
    private int plannedReservePremiumFruits2;
    @ManagedProperty(value = "#{plannedReserveEntityController}")
    PlannedReserveEntityController plannedReserveEntityController;
    @ManagedProperty(value = "#{reservationEntityController}")
    ReservationEntityController reservationEntityController;
    private long previousMonthOnHand = 0;

    public MasterProductionScheduleMonthlyEntityController() {
    }

    public MasterProductionScheduleMonthlyEntityFacade getEjbFacade() {
        return ejbFacade;
    }

    public void setEjbFacade(MasterProductionScheduleMonthlyEntityFacade ejbFacade) {
        this.ejbFacade = ejbFacade;
    }

    public int getPlannedReserveClassicFruits2() {
        this.setPlannedReserveClassicFruits(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable2.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                    plannedReserveClassicFruits2 = plannedReserveClassicFruits2 + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReserveClassicFruits;
    }

    public void setPlannedReserveClassicFruits2(int plannedReserveClassicFruits2) {
        this.plannedReserveClassicFruits2 = plannedReserveClassicFruits2;
    }

    public int getPlannedReserveClassicNuts2() {
        this.setPlannedReserveClassicNuts(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable2.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                    plannedReserveClassicNuts2 = plannedReserveClassicNuts2 + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReserveClassicNuts2;
    }

    public void setPlannedReserveClassicNuts2(int plannedReserveClassicNuts2) {
        this.plannedReserveClassicNuts2 = plannedReserveClassicNuts2;
    }

    public int getPlannedReservePremiumFruits2() {
        this.setPlannedReservePremiumFruits(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable2.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                    plannedReservePremiumFruits2 = plannedReservePremiumFruits2 + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReservePremiumFruits2;
    }

    public void setPlannedReservePremiumFruits2(int plannedReservePremiumFruits2) {
        this.plannedReservePremiumFruits2 = plannedReservePremiumFruits2;
    }

    public int getPlannedReservePremiumNuts2() {
        this.setPlannedReservePremiumNuts(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable2.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                    plannedReservePremiumNuts2 = plannedReservePremiumNuts2 + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReservePremiumNuts;
    }

    public void setPlannedReservePremiumNuts2(int plannedReservePremiumNuts2) {
        this.plannedReservePremiumNuts2 = plannedReservePremiumNuts2;
    }

    public DataTable getDataTable2() {
        return dataTable2;
    }

    public void setDataTable2(DataTable dataTable2) {
        this.dataTable2 = dataTable2;
    }

    public ReservationEntityController getReservationEntityController() {
        return reservationEntityController;
    }

    public void setReservationEntityController(ReservationEntityController reservationEntityController) {
        this.reservationEntityController = reservationEntityController;
        reservationEntityController.setMasterProductionScheduleMonthlyEntityController(this);
    }

    public int getPlannedReserveClassicNuts() {
        this.setPlannedReserveClassicNuts(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                    plannedReserveClassicNuts = plannedReserveClassicNuts + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReserveClassicNuts;
    }

    public int getPlannedReserveClassicFruits() {
        this.setPlannedReserveClassicFruits(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                    plannedReserveClassicFruits = plannedReserveClassicFruits + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReserveClassicFruits;
    }

    public void setPlannedReserveClassicFruits(int plannedReserveClassicFruits) {
        this.plannedReserveClassicFruits = plannedReserveClassicFruits;
    }

    public int getPlannedReservePremiumFruits() {
        this.setPlannedReservePremiumFruits(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                    plannedReservePremiumFruits = plannedReservePremiumFruits + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReservePremiumFruits;
    }

    public void setPlannedReservePremiumFruits(int plannedReservePremiumFruits) {
        this.plannedReservePremiumFruits = plannedReservePremiumFruits;
    }

    public int getPlannedReservePremiumNuts() {
        this.setPlannedReservePremiumNuts(0);
        MasterProductionScheduleMonthlyEntity mpsMonthly = (MasterProductionScheduleMonthlyEntity) dataTable.getRowData();
        List<PlannedReserveEntity> plannedReserves = new ArrayList(this.getPlannedReserveEntityController().getEjbFacade().findAll());
        for (PlannedReserveEntity plannedReserve : plannedReserves) {
            if (plannedReserve.getMonthOfProduction().equals(mpsMonthly.getMonthOfProduction())) {
                if (plannedReserve.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                    plannedReservePremiumNuts = plannedReservePremiumNuts + plannedReserve.getQuantity();
                }
            }
        }
        return plannedReservePremiumNuts;
    }

    public void setPlannedReservePremiumNuts(int plannedReservePremiumNuts) {
        this.plannedReservePremiumNuts = plannedReservePremiumNuts;
    }

    public PlannedReserveEntityController getPlannedReserveEntityController() {
        return plannedReserveEntityController;
    }

    public void setPlannedReserveEntityController(PlannedReserveEntityController plannedReserveEntityController) {
        this.plannedReserveEntityController = plannedReserveEntityController;
    }

    public void setPlannedReserveClassicNuts(int plannedReserveClassicNuts) {
        this.plannedReserveClassicNuts = plannedReserveClassicNuts;
    }

    public DataTable getDataTable() {
        return dataTable;
    }

    public void setDataTable(DataTable dataTable) {
        this.dataTable = dataTable;
    }

    public MasterProductionScheduleMonthlyEntity getSelected() {
        if (current == null) {
            current = new MasterProductionScheduleMonthlyEntity();
        }
        return current;
    }

    private MasterProductionScheduleMonthlyEntityFacade getFacade() {
        return ejbFacade;
    }

    public String create() {
        createProductionLine();
        yoy.setGenerated(true);
        yoyEjbFacade.edit(yoy);
        Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
        for (int i = 0; i < productionLine1Mps.size(); i++) {
            adjustOverallPercentage(productionLine1Mps.get(i), getCorrespondingMPS(productionLine1Mps.get(i)));
            calculateUtil(productionLine1Mps.get(i));
            calculateUtil(getCorrespondingMPS(productionLine1Mps.get(i)));
            getFacade().edit(productionLine1Mps.get(i));
            getFacade().edit(getCorrespondingMPS(productionLine1Mps.get(i)));
        }
        return "CreateMPSM";
    }

    private void createProductionLine() {
        for (int i = 0; i < 6; i++) {
            current = new MasterProductionScheduleMonthlyEntity();
            ArrayList salesForecast = new ArrayList<SalesForecastEntity>(yoy.getSalesForecast());
            SalesForecastEntity s = (SalesForecastEntity) salesForecast.get(i);
            current.setSalesForecast(s);
            current.setSalesForecastFigure(s.getForecast());
            current.setType(yoy.getForecastPeriodType());
            current.setProductionType(ProductionType.Classic);
            System.out.println("hereherehere"+s.getMonthOfSales());
            current.setMonthOfProduction(s.getMonthOfSales());
            current.setYearOfProduction(s.getYearOfSales());
            if (i == 0) {
                previousMonthOnHand = getFacade().getPreviousMonthOnHand(current);
                System.out.println("previousMonthOnHand=" + previousMonthOnHand);
            }
            int workingDays = calculateNumberOfWD(current.getSalesForecast().getMonthOfSales(), current.getSalesForecast().getYearOfSales());
            current.setMonthlyWorkingDays(workingDays);
            current.setCapacityNormal(calculateNumberOfHours(workingDays));
            current.setCapacityOverTime(calculateNumberOfOTHours(workingDays));
//            ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(s.getHistoricalPPQ());
//            current.setPlannedPPQ(createPPQ(ppq, current));
//            calculateProductionChangeByClassicNutsQuantity(current, current.getClassicNuts());
//            calculateProductionChangeByClassicFruitsQuantity(current, current.getClassicFruits());
//            calculateProductionChangeByPremiumNutsQuantity(current, current.getPremiumNuts());
//            calculateProductionChangeByPremiumFruitsQuantity(current, current.getPremiumFruits());
            setProductionLine2(new MasterProductionScheduleMonthlyEntity());
            ArrayList salesForecast2 = new ArrayList<SalesForecastEntity>(yoy.getSalesForecast());
            SalesForecastEntity s2 = (SalesForecastEntity) salesForecast2.get(i);
            getProductionLine2().setSalesForecast(s2);
            getProductionLine2().setSalesForecastFigure(s2.getForecast());
            getProductionLine2().setType(yoy.getForecastPeriodType());
            getProductionLine2().setProductionType(ProductionType.Premium);
            getProductionLine2().setMonthOfProduction(s2.getMonthOfSales());
            getProductionLine2().setYearOfProduction(s2.getYearOfSales());
            int workingDays2 = calculateNumberOfWD(getProductionLine2().getSalesForecast().getMonthOfSales(), getProductionLine2().getSalesForecast().getYearOfSales());
            getProductionLine2().setMonthlyWorkingDays(workingDays2);
            getProductionLine2().setCapacityNormal(calculateNumberOfHours(workingDays2));
            getProductionLine2().setCapacityOverTime(calculateNumberOfOTHours(workingDays2));
//            ArrayList<ProductPercentageQuantityEntity> ppq2 = new ArrayList<ProductPercentageQuantityEntity>(s2.getHistoricalPPQ());
//            getProductionLine2().setPlannedPPQ(createPPQ2(ppq2, getProductionLine2()));
//            calculateProductionChangeByClassicNutsQuantity(getProductionLine2(), getProductionLine2().getClassicNuts());
//            calculateProductionChangeByClassicFruitsQuantity(getProductionLine2(), getProductionLine2().getClassicFruits());
//            calculateProductionChangeByPremiumNutsQuantity(getProductionLine2(), getProductionLine2().getPremiumNuts());
//            calculateProductionChangeByPremiumFruitsQuantity(getProductionLine2(), getProductionLine2().getPremiumFruits());
//            adjustProductionLinePercentage(current);
//            adjustProductionLinePercentage(productionLine2);
//            calculateUtil(current);
//            calculateUtil(productionLine2);
//            current.setFulfilledFigure(current.getPlannedQuantity() + getProductionLine2().getPlannedQuantity());
//            getProductionLine2().setFulfilledFigure(current.getPlannedQuantity() + getProductionLine2().getPlannedQuantity());
//            current.setSafetyStock(calculateThisMonthOnHand(current, getFacade().getPreviousMonthOnHand(current)));
//            getProductionLine2().setSafetyStock(calculateThisMonthOnHand(productionLine2, getFacade().getPreviousMonthOnHand(productionLine2)));
            setTotalFulfillment(current, productionLine2, current.getSalesForecastFigure());
            create1();
            create2();
        }
        JsfUtil.addSuccessMessage("Sales Order Plan Generated");
    }
    
    public void setTotalFulfillment(MasterProductionScheduleMonthlyEntity mps, MasterProductionScheduleMonthlyEntity mps2, long totalQuantity) {
        //get sales forecast's ppq
         ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getSalesForecast().getHistoricalPPQ());
         if (mps.getProductionType().equals(ProductionType.Classic)) {
             mps.setPlannedPPQ(createPPQ(ppq,mps,totalQuantity));
             mps2.setPlannedPPQ(createPPQ2(ppq,mps2,totalQuantity));
             calculateProductionChangeByClassicNutsQuantity(mps, mps.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps, mps.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps, mps.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps, mps.getPremiumFruits());
             calculateProductionChangeByClassicNutsQuantity(mps2, mps2.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps2, mps2.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps2, mps2.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps2, mps2.getPremiumFruits());
             adjustProductionLinePercentage(mps);
             adjustProductionLinePercentage(mps2);
             calculateUtil(mps);
             calculateUtil(mps2);
             //re-adjust total
             mps.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps2.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps.setSafetyStock(calculateThisMonthOnHand(mps, getFacade().getPreviousMonthOnHand(mps)));
             mps2.setSafetyStock(calculateThisMonthOnHand(mps2, getFacade().getPreviousMonthOnHand(mps2)));
         }
         else {
             mps.setPlannedPPQ(createPPQ2(ppq,mps,totalQuantity));
             mps2.setPlannedPPQ(createPPQ(ppq,mps2,totalQuantity));
             calculateProductionChangeByClassicNutsQuantity(mps, mps.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps, mps.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps, mps.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps, mps.getPremiumFruits());
             calculateProductionChangeByClassicNutsQuantity(mps2, mps2.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps2, mps2.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps2, mps2.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps2, mps2.getPremiumFruits());
             adjustProductionLinePercentage(mps);
             adjustProductionLinePercentage(mps2);
             calculateUtil(mps);
             calculateUtil(mps2);
             //re-adjust total
             mps.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps2.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps.setSafetyStock(calculateThisMonthOnHand(mps, getFacade().getPreviousMonthOnHand(mps)));
             mps2.setSafetyStock(calculateThisMonthOnHand(mps2, getFacade().getPreviousMonthOnHand(mps2)));
         }
             
    }
    
    public void adjustTotalFulfillment(MasterProductionScheduleMonthlyEntity mps, long totalQuantity) {
        //get sales forecast's ppq
         ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getSalesForecast().getHistoricalPPQ());
         MasterProductionScheduleMonthlyEntity mps2 = getCorrespondingMPS(mps);
         if (mps.getProductionType().equals(ProductionType.Classic)) {
             mps.setPlannedPPQ(createPPQ(ppq,mps,totalQuantity));
             mps2.setPlannedPPQ(createPPQ2(ppq,mps2,totalQuantity));
             calculateProductionChangeByClassicNutsQuantity(mps, mps.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps, mps.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps, mps.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps, mps.getPremiumFruits());
             calculateProductionChangeByClassicNutsQuantity(mps2, mps2.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps2, mps2.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps2, mps2.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps2, mps2.getPremiumFruits());
             adjustProductionLinePercentage(mps);
             adjustProductionLinePercentage(mps2);
             calculateUtil(mps);
             calculateUtil(mps2);
             //re-adjust total
             mps.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps2.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
             mps2.setSafetyStock(calculateThisMonthOnHand(mps2, getPreviousMonthOnHand(mps2)));
         }
         else {
             mps.setPlannedPPQ(createPPQ2(ppq,mps,totalQuantity));
             mps2.setPlannedPPQ(createPPQ(ppq,mps2,totalQuantity));
             calculateProductionChangeByClassicNutsQuantity(mps, mps.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps, mps.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps, mps.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps, mps.getPremiumFruits());
             calculateProductionChangeByClassicNutsQuantity(mps2, mps2.getClassicNuts());
             calculateProductionChangeByClassicFruitsQuantity(mps2, mps2.getClassicFruits());
             calculateProductionChangeByPremiumNutsQuantity(mps2, mps2.getPremiumNuts());
             calculateProductionChangeByPremiumFruitsQuantity(mps2, mps2.getPremiumFruits());
             adjustProductionLinePercentage(mps);
             adjustProductionLinePercentage(mps2);
             calculateUtil(mps);
             calculateUtil(mps2);
             //re-adjust total
             mps.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps2.setFulfilledFigure(mps.getPlannedQuantity() + mps2.getPlannedQuantity());
             mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
             mps2.setSafetyStock(calculateThisMonthOnHand(mps2, getPreviousMonthOnHand(mps2)));
         }
          adjustAllOnHand(mps);   
    }
    
    private MasterProductionScheduleMonthlyEntity adjustAllOnHand(MasterProductionScheduleMonthlyEntity mps) {
        Vector<MasterProductionScheduleMonthlyEntity> month = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
        Vector<MasterProductionScheduleMonthlyEntity> month2 = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
        for (int i = 0; i < month.size(); i++) {
            if (!month.get(i).getMonthOfProduction().equals(mps.getMonthOfProduction())) {
                month.get(i).setSafetyStock(calculateThisMonthOnHand(month.get(i), getPreviousMonthOnHand(month.get(i))));
                month2.get(i).setSafetyStock(calculateThisMonthOnHand(month2.get(i), getPreviousMonthOnHand(month2.get(i))));
            }
        }
        return month.get(month.size()-1);
    }
    
    public void changeOnHand(MasterProductionScheduleMonthlyEntity mps) {
        ArrayList<MasterProductionScheduleMonthlyEntity> monthlyMPS = new ArrayList<MasterProductionScheduleMonthlyEntity>();
        monthlyMPS = getFacade().getAllMonthlyMPSFromMonthOnwards(adjustAllOnHand(mps));
        for (int i = 0; i < monthlyMPS.size(); i++) {
            monthlyMPS.get(i).setSafetyStock(calculateThisMonthOnHand(monthlyMPS.get(i),getFacade().getPreviousMonthOnHand(monthlyMPS.get(i))));
        }
    }
    
    private long getPreviousMonthOnHand(MasterProductionScheduleMonthlyEntity mps) {
        long onhand = 0;
        Vector<MasterProductionScheduleMonthlyEntity> month = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
        Vector<MasterProductionScheduleMonthlyEntity> month2 = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
        for (int i = 0; i < month.size(); i++) {
            if (month.get(i).getId() == mps.getId()) {
                if (i == 0)
                    onhand = previousMonthOnHand;
                else
                    onhand = month.get(i-1).getSafetyStock();
            }
            else if (month2.get(i).getId() == mps.getId()) {
                if (i == 0)
                    onhand = previousMonthOnHand;
                else
                    onhand = month.get(i-1).getSafetyStock();
            }
        }
        return onhand;
    }

    private ArrayList<ProductPercentageQuantityEntity> createPPQ(ArrayList<ProductPercentageQuantityEntity> ppq, MasterProductionScheduleMonthlyEntity mps, long totalQuantity) {
        ArrayList<ProductPercentageQuantityEntity> newppq = new ArrayList<ProductPercentageQuantityEntity>();
        long classic = 0;
        for (int i = 0; i < ppq.size(); i++) {
            ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
            p.setProduct(ppq.get(i).getProduct());
            //p.setPercentage(ppq.get(i).getPercentage());
            //set new quantity based on %
            //round up for any decimal point value
            //p.setQuantity((long) Math.ceil(ppq.get(i).getPercentage() * mps.getSalesForecastFigure()));
            p.setQuantity((long) Math.ceil(ppq.get(i).getPercentage() * totalQuantity));

            if (p.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                mps.setClassicNuts(p.getQuantity());
                classic = classic + mps.getClassicNuts();
            } else if (p.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                mps.setClassicFruits(p.getQuantity());
                classic = classic + mps.getClassicFruits();
            } else if (p.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                mps.setPremiumNuts(0);
                p.setQuantity(mps.getPremiumNuts());
            } else if (p.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                mps.setPremiumFruits(0);
                p.setQuantity(mps.getPremiumFruits());
            }
            mps.changePlannedQuantity();
            newppq.add(p);
        }
        for (int i = 0; i < newppq.size(); i++) {
            newppq.get(i).setPercentage(Math.round(newppq.get(i).getQuantity() * 1000.0 / classic) / 1000.0);
            System.out.println(newppq.get(i).getPercentage() + "%");
        }
        return newppq;
    }

    private ArrayList<ProductPercentageQuantityEntity> createPPQ2(ArrayList<ProductPercentageQuantityEntity> ppq, MasterProductionScheduleMonthlyEntity mps, long totalQuantity) {
        ArrayList<ProductPercentageQuantityEntity> newppq = new ArrayList<ProductPercentageQuantityEntity>();
        long premium = 0;
        for (int i = 0; i < ppq.size(); i++) {
            ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
            p.setProduct(ppq.get(i).getProduct());
            //p.setPercentage(ppq.get(i).getPercentage());
            //set new quantity based on %
            //round up for any decimal point value
            p.setQuantity((long) Math.ceil(ppq.get(i).getPercentage() * totalQuantity));

            if (p.getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                mps.setClassicNuts(0);
            } else if (p.getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                mps.setClassicFruits(0);
            } else if (p.getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                mps.setPremiumNuts(p.getQuantity());
                premium = premium + mps.getPremiumNuts();
            } else if (p.getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                mps.setPremiumFruits(p.getQuantity());
                premium = premium + mps.getClassicNuts();
            }
            mps.changePlannedQuantity();
            newppq.add(p);
        }
        for (int i = 0; i < newppq.size(); i++) {
            newppq.get(i).setPercentage(Math.round(newppq.get(i).getQuantity() * 1000.0 / premium) / 1000.0);
        }
        return newppq;
    }

    private void adjustProductionLinePercentage(MasterProductionScheduleMonthlyEntity mps) {
        DecimalFormat df = new DecimalFormat("0.000");
        double totalQuantity = mps.getPlannedQuantity();
        System.out.println("totalQuantity=" + totalQuantity);
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        for (int i = 0; i < ppq.size(); i++) {
            if (totalQuantity != 0) {
                double percentage = Double.valueOf(df.format(Math.round(ppq.get(i).getQuantity() * 1000 / totalQuantity) / 1000.0));
                ppq.get(i).setPercentage(percentage);
            } else {
                ppq.get(i).setPercentage(0);
            }
        }
        mps.setPlannedPPQ(ppq);
        dailyEjbFacade.updateDaily(mps);
    }

    private void adjustOverallPercentage(MasterProductionScheduleMonthlyEntity mps1, MasterProductionScheduleMonthlyEntity mps2) {
        DecimalFormat df = new DecimalFormat("0.000");
        double totalFulfilled = mps1.getFulfilledFigure();
        System.out.println("totalFulfilled=" + totalFulfilled);
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>();
        ArrayList<ProductPercentageQuantityEntity> ppq1 = new ArrayList<ProductPercentageQuantityEntity>(mps1.getPlannedPPQ());
        ArrayList<ProductPercentageQuantityEntity> ppq2 = new ArrayList<ProductPercentageQuantityEntity>(mps2.getPlannedPPQ());
        for (int i = 0; i < ppq1.size(); i++) {
            if (totalFulfilled != 0) {
                ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
                double percentage = Double.valueOf(df.format(Math.round((ppq1.get(i).getQuantity() + ppq2.get(i).getQuantity()) * 1000 / totalFulfilled) / 1000.0));
                p.setProduct(ppq1.get(i).getProduct());
                p.setPercentage(percentage);
                p.setQuantity(ppq1.get(i).getQuantity() + ppq2.get(i).getQuantity());
                ppq.add(p);
            } else {
                ProductPercentageQuantityEntity p = new ProductPercentageQuantityEntity();
                p.setProduct(ppq1.get(i).getProduct());
                p.setPercentage(0);
                p.setQuantity(0);
                ppq.add(p);
            }
        }
        mps1.setOverallPPQ(ppq);
        mps2.setOverallPPQ(ppq);
    }

    private MasterProductionScheduleMonthlyEntity getCorrespondingMPS(MasterProductionScheduleMonthlyEntity mps) {
        MasterProductionScheduleMonthlyEntity correspondingMps = new MasterProductionScheduleMonthlyEntity();
        if (mps.getProductionType().equals(ProductionType.Classic)) {
            Vector<MasterProductionScheduleMonthlyEntity> productionLine2Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
            productionLine2Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
            for (int i = 0; i < productionLine2Mps.size(); i++) {
                if (productionLine2Mps.get(i).getMonthOfProduction().equals(mps.getMonthOfProduction()) && productionLine2Mps.get(i).getYearOfProduction() == mps.getYearOfProduction()) {
                    correspondingMps = productionLine2Mps.get(i);
                }
            }
        } else if (mps.getProductionType().equals(ProductionType.Premium)) {
            Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
            productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
            for (int i = 0; i < productionLine1Mps.size(); i++) {
                if (productionLine1Mps.get(i).getMonthOfProduction().equals(mps.getMonthOfProduction()) && productionLine1Mps.get(i).getYearOfProduction() == mps.getYearOfProduction()) {
                    correspondingMps = productionLine1Mps.get(i);
                }
            }
        }
        return correspondingMps;
    }

    private void calculateUtil(MasterProductionScheduleMonthlyEntity mps) {
        System.out.println("calculating utilization");
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        double util = 0;
        for (int i = 0; i < ppq.size(); i++) {
            long quantity = ppq.get(i).getQuantity();
            util = util + ((1.0 / ppq.get(i).getProduct().getCasesOfHour()) * quantity);
        }
        util = util + dailyEjbFacade.calculateMonthlyChangeOverTime(mps);
        double maxNormal = (mps.getCapacityNormal() * 0.95);
        double otQuantity = 0;
        System.out.println("util:" + util + "changeOverTime:" + dailyEjbFacade.calculateMonthlyChangeOverTime(mps));
        System.out.println("maxNormal:" + maxNormal);
        if (util >= maxNormal) {
            otQuantity = Math.ceil(util - maxNormal);
            util = maxNormal;
            mps.setUtilizationNormal(Math.round((util / mps.getCapacityNormal()) * 1000) / 10);
            mps.setUtilizationOverTime(Math.round((otQuantity / mps.getCapacityNormal()) * 1000) / 10);
        } else {
            mps.setUtilizationNormal(Math.round((util / mps.getCapacityNormal()) * 1000) / 10);
            mps.setUtilizationOverTime(Math.round((otQuantity / mps.getCapacityNormal()) * 1000) / 10);
        }
    }
    
    public double calculateMonthlyChangeOverTime(MasterProductionScheduleMonthlyEntity mps) {
        return dailyEjbFacade.calculateMonthlyChangeOverTime(mps);
    }

    private double calculateNumberOfHours(int workingDays) {
        double numberOfHoursPerDay = 8;
        double numberOfHoursPerMonth = numberOfHoursPerDay * workingDays;
        return numberOfHoursPerMonth;
    }

    private double calculateNumberOfOTHours(int workingDays) {
        double numberOfHoursPerDay = 4;
        double numberOfHoursPerMonth = numberOfHoursPerDay * workingDays;
        return numberOfHoursPerMonth;
    }

    private int calculateNumberOfWD(Month month, int year) {
        //get total number of days in month
        int workingDays = getNumberOfDaysInMonth(month, year);
        //minus all saturdays and sundays
        workingDays = workingDays - getNumberOfWeekends(month, year);
        //query all ph
        ArrayList<CalendarEntity> ph = getFacade().getThisMonthPublicHoliday(month, year);
        //if ph not weekends minus from workingday
        for (int i = 0; i < ph.size(); i++) {
            if (!ph.get(i).getDayOfWeek().equals(DayOfWeek.Saturday) && !ph.get(i).getDayOfWeek().equals(DayOfWeek.Sunday)) {
                workingDays--;
            }
        }
        return workingDays;
    }

    private int getNumberOfDaysInMonth(Month month, int year) {
        Calendar cal = Calendar.getInstance();
        int mth = month.getMonthNum() - 1;
        cal.set(year, mth, 1);
        int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        return days;
    }

    private int getNumberOfWeekends(Month month, int year) {
        Date date;
        int numOfWeekends = 0;
        int mth = month.getMonthNum() - 1;
        for (int day = 1; day <= getNumberOfDaysInMonth(month, year); day++) {
            date = new Date(year - 1900, mth, day);
            if (date.getDay() == 0 || date.getDay() == 6) {
                numOfWeekends++;
            }
        }
        return numOfWeekends;
    }

    private void setFulfilled(MasterProductionScheduleMonthlyEntity mps) {
        Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        Vector<MasterProductionScheduleMonthlyEntity> productionLine2Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        if (mps.getProductionType().equals(ProductionType.Classic)) {
            productionLine1PlannedQuantity = mps.getPlannedQuantity();
            if (createItems2 != null) {
                productionLine2Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
                for (int i = 0; i < createItems2.getRowCount(); i++) {
                    if (mps.getMonthOfProduction().equals(productionLine2Mps.get(i).getMonthOfProduction())) {
                        productionLine2PlannedQuantity = productionLine2Mps.get(i).getPlannedQuantity();
                        productionLine2Mps.get(i).setFulfilledFigure(productionLine1PlannedQuantity + productionLine2PlannedQuantity);
                    }
                }
            }
        } else if (mps.getProductionType().equals(ProductionType.Premium)) {
            productionLine2PlannedQuantity = mps.getPlannedQuantity();
            if (createItems != null) {
                productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
                for (int i = 0; i < createItems.getRowCount(); i++) {
                    if (mps.getMonthOfProduction().equals(productionLine1Mps.get(i).getMonthOfProduction())) {
                        productionLine1PlannedQuantity = productionLine1Mps.get(i).getPlannedQuantity();
                        productionLine1Mps.get(i).setFulfilledFigure(productionLine1PlannedQuantity + productionLine2PlannedQuantity);
                    }
                }
            }
        }
        mps.setFulfilledFigure(productionLine1PlannedQuantity + productionLine2PlannedQuantity);
    }

    private long calculateThisMonthOnHand(MasterProductionScheduleMonthlyEntity mps, long previousMonth) {
        long thisMonthOnHand = 0;
        thisMonthOnHand = mps.getFulfilledFigure() - mps.getSalesForecastFigure() + previousMonth;
        System.out.println("thismonth="+mps.getMonthOfProduction()+"previousmonth="+previousMonth+"thismonth="+thisMonthOnHand);
        return thisMonthOnHand;
    }

    public void calculateUtilByClassicNutsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setClassicNuts(quantity);
        mps.changePlannedQuantity();
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(0).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
        //adjust percentage after insert quantity
        adjustProductionLinePercentage(mps);
        calculateUtil(mps);
        //set total fulfilled
        setFulfilled(mps);
        mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
        adjustAllOnHand(mps); 
        //adjust overall ppq
        adjustOverallPercentage(mps, getCorrespondingMPS(mps));
    }

    public void calculateUtilByClassicFruitsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setClassicFruits(quantity);
        mps.changePlannedQuantity();
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(1).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
        //adjust percentage after insert quantity
        adjustProductionLinePercentage(mps);
        calculateUtil(mps);
        //set total fulfilled
        setFulfilled(mps);
        mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
        adjustAllOnHand(mps); 
        //adjust overall ppq
        adjustOverallPercentage(mps, getCorrespondingMPS(mps));
    }

    public void calculateUtilByPremiumNutsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setPremiumNuts(quantity);
        mps.changePlannedQuantity();
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(2).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
        //adjust percentage after insert quantity
        adjustProductionLinePercentage(mps);
        calculateUtil(mps);
        //set total fulfilled
        setFulfilled(mps);
        mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
        adjustAllOnHand(mps); 
        //adjust overall ppq
        adjustOverallPercentage(mps, getCorrespondingMPS(mps));
    }

    public void calculateUtilByPremiumFruitsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setPremiumFruits(quantity);
        mps.changePlannedQuantity();
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(3).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
        //adjust percentage after insert quantity
        adjustProductionLinePercentage(mps);
        calculateUtil(mps);
        //set total fulfilled
        setFulfilled(mps);
        mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
        adjustAllOnHand(mps); 
        //adjust overall ppq
        adjustOverallPercentage(mps, getCorrespondingMPS(mps));
    }

    public void changeProductionPlan(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        System.out.println("changeProductionPlan");
        mps.setPlannedQuantity(quantity);
        //adjust quantity for each product according to it's percentage set
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        double percentage = 0;
        for (int i = 0; i < ppq.size(); i++) {
            long qty = Math.round(ppq.get(i).getPercentage() * quantity);
            percentage = percentage + ppq.get(i).getPercentage();
            System.out.println("qty=" + qty + "percentage=" + ppq.get(i).getPercentage());
            if (ppq.get(i).getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                calculateProductionChangeByClassicNutsQuantity(mps, qty);
            } else if (ppq.get(i).getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                calculateProductionChangeByClassicFruitsQuantity(mps, qty);
            } else if (ppq.get(i).getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                calculateProductionChangeByPremiumNutsQuantity(mps, qty);
            } else if (ppq.get(i).getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                calculateProductionChangeByPremiumFruitsQuantity(mps, qty);
            }
        }
        if (percentage == 0) {
            //set back to original percentage
            //get production type first
            if (mps.getProductionType().equals(ProductionType.Classic)) {
                mps.setPlannedPPQ(createPPQ(new ArrayList<ProductPercentageQuantityEntity>(mps.getSalesForecast().getHistoricalPPQ()), mps, mps.getSalesForecastFigure()));
            } else if (mps.getProductionType().equals(ProductionType.Premium)) {
                mps.setPlannedPPQ(createPPQ2(new ArrayList<ProductPercentageQuantityEntity>(mps.getSalesForecast().getHistoricalPPQ()), mps, mps.getSalesForecastFigure()));
            }
            ArrayList<ProductPercentageQuantityEntity> newppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
            for (int i = 0; i < newppq.size(); i++) {
                long qty = Math.round(newppq.get(i).getPercentage() * quantity);
                System.out.println("qty=" + qty + "percentage=" + newppq.get(i).getPercentage());
                if (newppq.get(i).getProduct().getProductName().equals("Classic Nutri Bar (Nuts)")) {
                    calculateProductionChangeByClassicNutsQuantity(mps, qty);
                } else if (newppq.get(i).getProduct().getProductName().equals("Classic Nutri Bar (Fruits)")) {
                    calculateProductionChangeByClassicFruitsQuantity(mps, qty);
                } else if (newppq.get(i).getProduct().getProductName().equals("Premium Power Bar (Chocolate Nuts)")) {
                    calculateProductionChangeByPremiumNutsQuantity(mps, qty);
                } else if (newppq.get(i).getProduct().getProductName().equals("Premium Power Bar (Redcurrant Fruits)")) {
                    calculateProductionChangeByPremiumFruitsQuantity(mps, qty);
                }
            }
        }
        mps.changePlannedQuantity();
        adjustProductionLinePercentage(mps);
        calculateUtil(mps);
        //set total fulfilled
        setFulfilled(mps);
        mps.setSafetyStock(calculateThisMonthOnHand(mps, getPreviousMonthOnHand(mps)));
        adjustAllOnHand(mps); 
        //adjust overall ppq
        adjustOverallPercentage(mps, getCorrespondingMPS(mps));
    }

    public void calculateProductionChangeByClassicNutsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setClassicNuts(quantity);
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(0).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
    }

    public void calculateProductionChangeByClassicFruitsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setClassicFruits(quantity);
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(1).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
    }

    public void calculateProductionChangeByPremiumNutsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setPremiumNuts(quantity);
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(2).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
    }

    public void calculateProductionChangeByPremiumFruitsQuantity(MasterProductionScheduleMonthlyEntity mps, long quantity) {
        //set total plan quantity
        mps.setPremiumFruits(quantity);
        //set quantity into ppq
        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
        ppq.get(3).setQuantity(quantity);
        mps.setPlannedPPQ(ppq);
    }

    public void changePercentage(MasterProductionScheduleMonthlyEntity mps) {
        System.out.println("changePercentage");
//        ArrayList<ProductPercentageQuantityEntity> ppq = new ArrayList<ProductPercentageQuantityEntity>(mps.getPlannedPPQ());
//        for (int i = 0; i < ppq.size(); i++) {
//            if (ppq.get(i).getProduct() == product) {
//                ppq.get(i).setPercentage(percentage);
//            }
//        }
//        mps.setPlannedPPQ(ppq);
        
        changeProductionPlan(mps, mps.getPlannedQuantity());
    }

    public String prepareList() {
        recreateModel();
        return "/entities/masterProductionScheduleMonthlyEntity/List?faces-redirect=true";
    }

    public void prepareListNoRedirect() {
        recreateModel();
    }

    public String prepareView() {
        current = (MasterProductionScheduleMonthlyEntity) getItems().getRowData();
        previousMonthOnHand = getFacade().getPreviousMonthOnHand(current);
        setCreateItems(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Classic));
        setCreateItems2(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Premium));
        return "View";
    }

    public void prepareViewNoRedirect() {
        current = (MasterProductionScheduleMonthlyEntity) getItems().getRowData();
        setCreateItems(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Classic));
        setCreateItems2(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Premium));
    }

    public String prepareCreate() {
        //current = new MasterProductionScheduleMonthlyEntity();
        return "Create";
    }

    public String create1() {
        try {
            productionLine1PlannedQuantity = current.getPlannedQuantity();
            current.created(getLoginPerson());
            createDailyMPS(current);
            getFacade().create(current);
            createWeeklyMPS(current);
            setCreateItems(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), current.getProductionType()));
            //JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MasterProductionScheduleMonthlyEntityCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            e.printStackTrace();
            return null;
        }
    }

    public String create2() {
        try {
            productionLine2PlannedQuantity = getProductionLine2().getPlannedQuantity();
            getProductionLine2().created(getLoginPerson());
            createDailyMPS(productionLine2);
            getFacade().create(getProductionLine2());
            createWeeklyMPS(productionLine2);
            setCreateItems2(getFacade().listCreateMPS(getProductionLine2().getType(), getProductionLine2().getYearOfProduction(), getProductionLine2().getProductionType()));
            //JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MasterProductionScheduleMonthlyEntityCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            e.printStackTrace();
            return null;
        }
    }

    public void createDailyMPS(MasterProductionScheduleMonthlyEntity monthlyMPS) {
        dailyEjbFacade.createDaily(monthlyMPS);
    }
    
    public void createWeeklyMPS(MasterProductionScheduleMonthlyEntity monthlyMPS) {
        dailyEjbFacade.createWeekly(monthlyMPS);
    }

    public String prepareEdit() {
        previousMonthOnHand = getFacade().getPreviousMonthOnHand(current);
        setCreateItems(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Classic));
        setCreateItems2(getFacade().listCreateMPS(current.getType(), current.getYearOfProduction(), ProductionType.Premium));
        return "CreateMPSM";
    }

    public String update() {
        try {
            Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
            Vector<MasterProductionScheduleMonthlyEntity> productionLine2Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
            productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
            productionLine2Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
            for (int i = 0; i < createItems.getRowCount(); i++) {
                current = productionLine1Mps.get(i);
                setProductionLine2(productionLine2Mps.get(i));
                current.modified(getLoginPerson());
                getProductionLine2().modified(getLoginPerson());
                getFacade().edit(current);
                getFacade().edit(getProductionLine2());
                dailyEjbFacade.editAll(new ArrayList<MasterProductionScheduleDailyEntity>(current.getMpsDaily()));
                dailyEjbFacade.editAll(new ArrayList<MasterProductionScheduleDailyEntity>(productionLine2.getMpsDaily()));
            }
            JsfUtil.addSuccessMessage("Sales Operation Plan saved");
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current.modified(getLoginPerson());
        current = (MasterProductionScheduleMonthlyEntity) getItems().getRowData();
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        return "List";
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("MasterProductionScheduleMonthlyEntityDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getFacade().displayMPSByPeriod();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    public ExpectedYearOnYearGrowthEntity getYoy() {
        return yoy;
    }

    public void setYoy(ExpectedYearOnYearGrowthEntity yoy) {
        this.yoy = yoy;
    }

    public DataModel getCreateItems() {
        return createItems;
    }

    public void setCreateItems(DataModel createItems) {
        this.createItems = createItems;
    }

    public DataModel getCreateItems2() {
        return createItems2;
    }

    public void setCreateItems2(DataModel createItems2) {
        this.createItems2 = createItems2;
    }

    public long getPreviousMonthOnHand() {
        return previousMonthOnHand;
    }

    public void setPreviousMonthOnHand(long previousMonthOnHand) {
        this.previousMonthOnHand = previousMonthOnHand;
    }

    public MasterProductionScheduleMonthlyEntity getProductionLine2() {
        return productionLine2;
    }

    public void setProductionLine2(MasterProductionScheduleMonthlyEntity productionLine2) {
        this.productionLine2 = productionLine2;
    }

    @FacesConverter(forClass = MasterProductionScheduleMonthlyEntity.class)
    public static class MasterProductionScheduleMonthlyEntityControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            MasterProductionScheduleMonthlyEntityController controller = (MasterProductionScheduleMonthlyEntityController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "masterProductionScheduleMonthlyEntityController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof MasterProductionScheduleMonthlyEntity) {
                MasterProductionScheduleMonthlyEntity o = (MasterProductionScheduleMonthlyEntity) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + MasterProductionScheduleMonthlyEntityController.class.getName());
            }
        }
    }

    public boolean checkPercentage(double utilization) {
        if (utilization > 95) {
            return true;
        } else {
            return false;
        }
    }

    public boolean checkAllPercentage() {
        Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        Vector<MasterProductionScheduleMonthlyEntity> productionLine2Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
        productionLine2Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems2.getWrappedData();
        for (int i = 0; i < productionLine1Mps.size(); i++) {
            if (productionLine1Mps.get(i).getUtilizationOverTime() > 95) {
                return true;
            }
        }
        for (int i = 0; i < productionLine2Mps.size(); i++) {
            if (productionLine2Mps.get(i).getUtilizationOverTime() > 95) {
                return true;
            }
        }
        return false;
    }

    public boolean checkOnHand() {
        Vector<MasterProductionScheduleMonthlyEntity> productionLine1Mps = new Vector<MasterProductionScheduleMonthlyEntity>();
        productionLine1Mps = (Vector<MasterProductionScheduleMonthlyEntity>) createItems.getWrappedData();
        for (int i = 0; i < productionLine1Mps.size(); i++) {
            if (productionLine1Mps.get(i).getSafetyStock() < 0) {
                return true;
            }
        }
        return false;
    }

    public boolean checkNegativeOnHand(long onHand) {
        if (onHand < 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean checkPercentageEqualsRecommendation(MasterProductionScheduleMonthlyEntity mps, ProductPercentageQuantityEntity overallPPQ) {
        boolean recommended = false;
        ArrayList<ProductPercentageQuantityEntity> salesForecastPPQ = new ArrayList<ProductPercentageQuantityEntity>(mps.getSalesForecast().getHistoricalPPQ());
        for (int i = 0; i < salesForecastPPQ.size(); i++) {
            if (salesForecastPPQ.get(i).getProduct() == overallPPQ.getProduct())
                if (Math.abs(salesForecastPPQ.get(i).getPercentage() - overallPPQ.getPercentage()) < 0.05) {
                    System.out.println("salesForecast"+salesForecastPPQ.get(i).getPercentage()+"overall="+overallPPQ.getPercentage());
                    recommended = true;
                }
        }
        return recommended;
    }
}
